import wave
import math
import os
import struct
import numpy as np

def en(wave_data, window_size, head_size, frame_size):
    start_location = head_size
    end_location = head_size + window_size
    result = []
    while(end_location != frame_size):
        temp_en = 0
        for m in range(start_location, end_location):
            temp_en = temp_en + pow(wave_data[m], 2)
        result += [temp_en]
        end_location = end_location + window_size
        if end_location < frame_size :
            start_location = start_location + window_size
        else:
            end_location = frame_size
    return result

def zero(wave_data, window_size, head_size, frame_size):
    start_location = head_size
    end_location = head_size + window_size
    result = []
    while(end_location != frame_size):
        temp_zero = 0
        for m in range(start_location + 1, end_location):
            if (wave_data[m] * wave_data[m-1]) > 0 :
                temp_zero = temp_zero
            else:
                temp_zero = temp_zero + 1
        result += [temp_zero*window_size]
        end_location = end_location + window_size
        if end_location < frame_size :
            start_location = start_location + window_size
        else:
            end_location = frame_size
    return result

def VAD(en_data, zero_data, wave_data):
    energy_low = 10000000
    zero_low = 10000
    pcm_data = []
    if len(en_data) <= len(zero_data):
        max = len(en_data)
    else:
        max = len(zero_data)
    recorder = 0
    start_mark = False
    for i in range(0, max):
        if en_data[i] > energy_low and zero_data[i] > zero_low:
            if start_mark == False:
                recorder = recorder + 1
                if recorder > 3:
                    start_mark = True
                    recorder = 0
                    for n in range(0, 3):
                        for m in range((i-3+n)*256, (i-3+n)*256+255):
                            pcm_data += [wave_data[m]]
                else:
                    continue
            else:
                for m in range(i*256, i*256+255):
                    pcm_data += [wave_data[m]]
        else:
            start_mark = False
            recorder = 0
    return pcm_data

def main():
    path = os.path.abspath('.') + '/wav_files/'
    VAD_path = os.path.abspath('.') + '/VAD_files/'
    file_list = os.listdir(path)
    for file in file_list:
        file_info = os.path.splitext(file)
        file_name = file_info[0]
        file_path = path + file
        print(file_path)
        f = wave.open(file_path, 'rb')
        nframes = f.getnframes()
        framerate = f.getframerate()
        temp_data = f.readframes(nframes)
        wave_data = np.fromstring(temp_data, dtype=np.int16)
        f.close()
        en_data = en(wave_data, 256, 44, nframes)
        zero_data = zero(wave_data, 256, 44, nframes)
        pcm_data = VAD(en_data, zero_data, wave_data)
        VAD_file = VAD_path + file_name + '.pcm'
        byte_pcm_data = b''.join(pcm_data)
        file_write = wave.open(VAD_file, 'wb')
        file_write.setframerate(framerate)
        file_write.setnchannels(1)
        file_write.setsampwidth(2)
        file_write.writeframes(byte_pcm_data)
        file_write.close()


        
        # 可直观显示结果的代码，最终代码无需用到
        
        # time = np.arange(0, len(wave_data)) * (1.0 / framerate)
        # time2 = np.arange(0, len(pcm_data)) * (1.0 / framerate)
        # pl.subplot(211)
        # pl.plot(time, wave_data)
        # pl.ylabel("Amplitude")
        # pl.subplot(212)
        # pl.plot(time2, pcm_data)
        # pl.ylabel("ZCR")
        # pl.xlabel("time (seconds)")
        # pl.show()
        

main()